<template>
    <div ref="container" class="x6-graph" @contextmenu.prevent></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount,reactive } from 'vue'
import { Graph } from '@antv/x6'

const container = ref(null)
let graph = null

// 统一连线状态管理
const connectionState = reactive({
    isConnecting: false,
    sourceNode: null,
    tempEdge: null
})

// 创建节点模板
const createNode = (x, y, label) => ({
    x,
    y,
    width: 100,
    height: 40,
    label,
    attrs: {
        body: {
            fill: '#fff',
            stroke: '#1890ff',
            strokeWidth: 1
        },
        label: {
            text: label,
            fill: '#333'
        }
    }
})

// 注册自定义连线（优化箭头样式）
Graph.registerEdge('custom-edge', {
    inherit: 'edge',
    attrs: {
        line: {
            stroke: '#1890ff',
            strokeWidth: 2,
            targetMarker: {
                name: 'classic',
                size: 8,
                fill: '#1890ff'
            }
        }
    },
    zIndex: 0
}, true)

// 初始化连线逻辑
const initConnection = () => {
    const handleMouseDown = (e) => {
        if (e.button !== 2) return // 仅处理右键
        
        const node = getNodeAtPoint(e.clientX, e.clientY)
        if (node) {
            startConnection(node, e.clientX, e.clientY)
        }
    }

    const handleMouseMove = (e) => {
        if (!connectionState.isConnecting) return
        
        const point = graph.clientToLocal(e.clientX, e.clientY)
        connectionState.tempEdge.setTarget(point)
    }

    const handleMouseUp = (e) => {
        if (!connectionState.isConnecting) return
        
        const node = getNodeAtPoint(e.clientX, e.clientY)
        if (node && node.id !== connectionState.sourceNode.id) {
            completeConnection(node)
        } else {
            cancelConnection()
        }
    }

    window.addEventListener('mousedown', handleMouseDown)
    window.addEventListener('mousemove', handleMouseMove)
    window.addEventListener('mouseup', handleMouseUp)

    onBeforeUnmount(() => {
        window.removeEventListener('mousedown', handleMouseDown)
        window.removeEventListener('mousemove', handleMouseMove)
        window.removeEventListener('mouseup', handleMouseUp)
    })
}

// 获取节点（优化性能）
const getNodeAtPoint = (x, y) => {
    const point = graph.clientToLocal(x, y)
    return graph.getNodes().find(node => 
        node.getBBox().containsPoint(point)
    )
}

// 开始连线
const startConnection = (sourceNode, x, y) => {
    const point = graph.clientToLocal(x, y)
    
    connectionState.isConnecting = true
    connectionState.sourceNode = sourceNode
    
    connectionState.tempEdge = graph.addEdge({
        shape: 'custom-edge',
        source: { cell: sourceNode.id },
        target: point,
        attrs: {
            line: {
                strokeDasharray: '5 5'
            }
        }
    })
}

// 完成连线
const completeConnection = (targetNode) => {
    graph.removeEdge(connectionState.tempEdge);

    console.log("connectionState",connectionState)
    
    graph.addEdge({
        shape: 'custom-edge',
        source: { cell: connectionState.sourceNode.id },
        target: { cell: targetNode.id },
        data: {
            from: connectionState.sourceNode.data.label,
            to: targetNode.data.label,
            createdAt: new Date().toISOString()
        }
    })
    
    resetConnection()
}

// 重置连线状态
const resetConnection = () => {
    connectionState.isConnecting = false
    connectionState.sourceNode = null
    connectionState.tempEdge = null
}

// 取消连线
const cancelConnection = () => {
    if (connectionState.tempEdge) {
        graph.removeEdge(connectionState.tempEdge)
    }
    resetConnection()
}

onMounted(() => {
    graph = new Graph({
        container: container.value,
        grid: true,
        panning: true,
        background: { color: '#f5f5f5' }
    })

    // 添加示例节点
    graph.addNode(createNode(100, 100, 'Node A'))
    graph.addNode(createNode(400, 300, 'Node B'))

    initConnection()
})
</script>

<style>
.x6-graph {
    width: 100%;
    height: 600px;
    border: 1px solid #e8e8e8;
}
</style>